#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cerrno>
#include <netinet/in.h>
#include <arpa/inet.h>
namespace client
{
    using namespace std;
    class udpClient
    {
    public:
        udpClient(uint16_t ServerPort, string ServerIp) : _ServerIp(ServerIp), _ServerPort(ServerPort), _socketfd(-1)
        {
        }
        void Init()
        {
            _socketfd = socket(AF_INET, SOCK_DGRAM, 0);
            if (_socketfd == -1)
            {
                cerr << "Client err" << errno << strerror(errno) << endl;
                exit(2);
            }
            cout<<"sucess :"<<_socketfd<<endl;
            // Client也需要bind，只不过是os来bind，而不是程序员来bind
        }
        void run()
        {
            struct sockaddr_in peer;
            memset(&peer, 0, sizeof peer);
            peer.sin_family = AF_INET;
            peer.sin_port = htons(_ServerPort);
            peer.sin_addr.s_addr = inet_addr(_ServerIp.c_str());
            string message;
            char buffer[1024];
            while (1)
            {
                cout << "#";
                fgets(buffer,sizeof buffer,stdin);
                buffer[strlen(buffer)-1] = 0;
                message = buffer;
                int n = sendto(_socketfd, message.c_str(), message.size(), 0, (struct sockaddr *)&peer,sizeof peer);
                struct sockaddr_in Server;
                char buffer[1024];
                socklen_t len = sizeof(Server);
                int k = recvfrom(_socketfd,buffer,sizeof buffer,0,(struct sockaddr*)&Server,&len);
                if(k>=0)
                buffer[k] = 0;
                cout<<buffer<<endl; 
            }
        }
        ~udpClient()
        {
        }

    private:
        int _socketfd;
        uint16_t _ServerPort;
        string _ServerIp;
    };
}
